#include "CCmdSendMallGoods.h"
#include "../cmd/dataprepare.h"
#include "../mainctrl.h"
#include "commmsg.h"
#include "commclass.h"
#include "../oss/COssMgr.h"
#include "CTCodeConvert3.h"
#include "../cmd/cmdapi.h"
#include "../vip/CVipMgr.h"

CT_REGISTER_ASYNCCMD(ID_MAIN_INNER_SEND_GOLD , CCmdSendGold);

int CCmdSendGold::Do(void* pData)
{
    if (pData != NULL)
    {
        CT_WARNING(("inner cmd CCmdSendGold get data"));
        return AnsClients(RET_SYS_ERROR);
    }

    if (pstMainCtrl == NULL)
    {
        CT_ERROR(("mainctrl point is null"));
        return AnsClients(RET_SYS_ERROR);
    }

    bHasGetYellowInfo = false;
    LogicDo(RET_OK);
    return RET_OK;
}

int CCmdSendGold::LogicDo(int iRet)
{
    if (iRet != RET_OK)
    {
        CT_ERROR(("CCmdSendGold error , ret %d", iRet));
        return AnsClients(RET_SYS_ERROR);
    }

    PREPARE_PLAYER_BASE_INFO(this, uiGID);
    PREPARE_PLAYER_DETAIL_INFO(this, uiGID);
    PREPARE_PLAYER_ONLINE_DATA(this, uiGID);
    PREPARE_PLAYER_DETAIL_EX1_INFO(this, uiGID);

    int iIndex = pstMainCtrl->m_stPlayerBaseInfoHash.HashFind(uiGID);
    if (iIndex < 0)
    {
        CT_ERROR(("online user %u has no base info", uiGID));
        return AnsClients(RET_SYSTEM_FAIL);
    }
    CPlayerBaseInfo& stPlayerBaseInfo = pstMainCtrl->m_stPlayerBaseInfoHash[iIndex];

    iIndex = pstMainCtrl->m_stPlayerDetailInfoHash.HashFind(uiGID);
    if (iIndex < 0)
    {
        CT_ERROR(("online user %u has no detail info", uiGID));
        return AnsClients(RET_SYSTEM_FAIL);
    }
    CPlayerDetailInfo& stPlayerDetailInfo = pstMainCtrl->m_stPlayerDetailInfoHash[iIndex];

    iIndex = pstMainCtrl->m_stPlayerDetailEx1InfoHash.HashFind(uiGID);
    if (iIndex < 0)
    {
        CT_ERROR(("online user %u has no detail ex1 info", uiGID));
        return AnsClients(RET_SYS_ERROR);
    }
    CPlayerDetailInfoEx1 & stPlayerDetailInfoEx1 = pstMainCtrl->m_stPlayerDetailEx1InfoHash[iIndex];

    iIndex = pstMainCtrl->m_stPlayerOnlineDataHash.HashFind(uiGID);
    if (iIndex < 0)
    {
        CT_ERROR(("gid = %u", uiGID));
        return AnsClients(RET_SYS_ERROR);
    }
    CPlayerOnlineData& stPlayerOnlineData = pstMainCtrl->m_stPlayerOnlineDataHash[iIndex];

    //获取黄钻信息
    bool bIsYellow = false;
    bool bIsBlue = false;
    bool bIsVip = false;
    if (!bHasGetYellowInfo)
    {
        bHasGetYellowInfo = true;

        //平台校验登录
        CCmdApi* pstCmd = (CCmdApi*)CT_CMDFACTORY->CreateCmd(ID_MAINAPI_TAPI);
        if (!pstCmd)
        {
            CT_WARNING(("create cmd error"));
            return AnsClients(RET_SYS_ERROR);
        }

        pstCmd->pstMainCtrl = CMainCtrl::m_pstMain;
        pstCmd->stReq._ucReqType = CReqApi::API_TENCENT;
        pstCmd->stReq._szTApiName.Set("/v3/user/total_vip_info");
        pstCmd->stReq._stTApiKeyValue = stPlayerOnlineData._stTencentApiKeyValue;

        RegisterChild(pstCmd, true);
        return pstCmd->Do(NULL);
    }

    if (m_pstChild && ID_MAINAPI_TAPI == m_pstChild->GetCmdID())
    {
        CCmdApi* pstCmd = (CCmdApi*)m_pstChild;

        bIsYellow = atoi(pstCmd->stAns._stTApiKeyValue.GetValue("is_yellow")) == 1;
        bIsBlue = atoi(pstCmd->stAns._stTApiKeyValue.GetValue("is_blue")) == 1;
    }

    if ((TENCENT_LOGIN_FROM_QQGAME == stPlayerOnlineData._ucTencentLoginFrom
        || TENCENT_LOGIN_FROM_3366 == stPlayerOnlineData._ucTencentLoginFrom)
        && bIsBlue)
    {
        bIsVip = true;
    }
    else if ((TENCENT_LOGIN_FROM_QZONE == stPlayerOnlineData._ucTencentLoginFrom
        || TENCENT_LOGIN_FROM_PENGYOU == stPlayerOnlineData._ucTencentLoginFrom)
        && bIsYellow)
    {
        bIsVip = true;
    }

    if (bIsVip) //VIP用户缺省送VIP1级
    {
        //平台VIP用户缺省送VIP1级
        pstMainCtrl->m_stVipMgr.SetYellowDefaultVip(stPlayerBaseInfo);
    }

    //#if 0
    //GM修改时间后的发货,要用服务器的原始时间
    int iPayTime = atoi(stPara.GetValue("ts"));
    if (pstMainCtrl->m_iNow - iPayTime >= 14 * 60)
    {
        stAns.msg.Set("交易的token已过期");
        return AnsClients(2);
    }
    //#endif

    if (0 != strcmp(stPlayerOnlineData._szTencentPayToken(), stPara.GetValue("token")))
    {
        stAns.msg.Set("交易的token不存在");
        return AnsClients(3);
    }

    //获取交易内容
    std::string s = stPara.GetValue("payitem");
    const std::string del = "*";
    std::vector<string> vBuyContent;

    CTLib::CTStringUtils::Split(s, del, vBuyContent);

    if (vBuyContent.size() != 3) //只会有3个参数
    {
        stAns.msg.Set("payitem 格式错误");
        return AnsClients(4);  //腾讯的错误码 请求参数错误
    }

    unsigned int uiGoodsId = atoi(vBuyContent[0].c_str());
    int iCount = atoi(vBuyContent[2].c_str());

    if (DEFAULT_GOODS_ID_32WAN == uiGoodsId)
    {
        stAns.msg.Set("不能购买32玩平台的商品.");
        return AnsClients(4);
    }

    //成长基金检查
    if (GROW_FUND_GOODS_ID == uiGoodsId)
    {
        if (iCount != 1)
        {
            stAns.msg.Set("成长基金数量出错. %d", iCount);
            return AnsClients(4);
        }

        if (stPlayerDetailInfoEx1._stPayActData._ucHasBuyGrowFund != 0)
        {
            stAns.msg.Set("已经购买成长基金.");
            return AnsClients(4);
        }
    }

    //如果是限量商品,记录已购买的个数
    bool bHasBuyLimitedGoods = false;
    bool bUpdateDetailEx1 = false;
    if (pstMainCtrl->m_stQQMallMgr.IsLimitGoods(uiGoodsId))
    {
        //检查用户是否购买的物品数，是否超量了
        iRet = pstMainCtrl->m_stQQMallMgr.CheckBuyLimit (stPlayerDetailInfoEx1._stUserMall, uiGoodsId, iCount, pstMainCtrl->m_iNow);
        if (iRet)
        {
            stAns.msg.Set("购买限量商品出错. %d", iRet);
            return AnsClients(4);
        }

        bHasBuyLimitedGoods = true;
    }

    CDropItem stDropItem;

    if (GROW_FUND_GOODS_ID == uiGoodsId)
    {
        //成长基金发货
        stPlayerDetailInfoEx1._stPayActData._ucHasBuyGrowFund = 1;
        pstMainCtrl->m_stActMgr.SendGrowFundInfo(stPlayerDetailInfoEx1._stPayActData, uiGID);
        bUpdateDetailEx1 = true;

        //发送跑马灯
        MsgTips stTips;
        stTips.set_type(1066);
        stTips.add_tip_argument(CMainCtrl::m_pstMain->m_stRoleMgr.GetRoleName(uiGID));

        CMainCtrl::m_pstMain->SendOnlineTips(stTips);
    }
    else
    {
        //发货
        iRet = pstMainCtrl->m_stShopMgr.DeliverGoods(stPlayerOnlineData, stPlayerBaseInfo, stPlayerDetailInfo, stPlayerDetailInfoEx1,
            uiGoodsId, iCount, DELIVER_GOODS_QQ, stDropItem);
        if (iRet)
        {
            return AnsClients(iRet);
        }
    }

    //清空状态
    stPlayerOnlineData._szTencentPayToken.SetDataLen(0);

    pstMainCtrl->m_stOssMgr.TriggerMoney (uiGID, OSS_MONEY_BUY_GOODS, uiGoodsId, iCount);
    //用户实际支付的Q点数
    int iQcent = atoi(stPara.GetValue("amt"));
    if (iQcent > 0)
    {
        int iVipExp = pstMainCtrl->m_stQQMallMgr.GetMallGoodsVipExp(uiGoodsId, iCount);
        if (stPlayerBaseInfo._stVipData._iPayGold <= 0)
        {
            //记录首充
            pstMainCtrl->m_stOssMgr.TriggerMoney (uiGID, OSS_MONEY_FIRST_BUY, uiGoodsId, iCount);
            pstMainCtrl->m_stOssMgr.TriggerFirstPay(uiGID, iQcent);
        }

        //记录充值的OSS信息
        pstMainCtrl->m_stOssMgr.TriggerMoney(uiGID, OSS_MONEY_ADD_GOLD, OSS_MODULE_VIP, iQcent);

        //消费返利记录用
        unsigned char ucOldVipLevel = stPlayerBaseInfo._chVipLevel;

        //修改VIP
        pstMainCtrl->m_stVipMgr.PrepaidGold(stPlayerBaseInfo, stPlayerDetailInfo, iVipExp, bIsVip);

        //记录消费返利
        //stPlayerDetailInfoEx1._stPayActData.AddQPoint(ucOldVipLevel, iVipExp, pstMainCtrl->m_iNow);

        //保存数据
        //bUpdateDetailEx1 = true;

        //腾讯罗盘
        for (int i = 0; i < stDropItem.Size(); i++)
        {
            CDropItemData & stData = stDropItem._astDropItem[i];
            pstMainCtrl->m_stCompassMgr.Recharge(uiGID, iQcent, stData._usItemConfigID, stData._iItemCount,
                stData._ucItemType, stPlayerBaseInfo._iGold);
        }

        if (ucOldVipLevel != stPlayerBaseInfo._chVipLevel)
        {
            pstMainCtrl->m_stNotifyMgr.Notify(uiGID, NOTIFY_SYSOPEN_INFO);
            pstMainCtrl->FlushSendCache();
        }

        //QQ好友邀请
        pstMainCtrl->m_stFriendMgr.BeInvitedRoleTrigger(stPlayerDetailInfoEx1,
            CFriendMgr::CMD_QQ_FRIEND_SUB_ADD_PAY_ANY_NUM,
            stPlayerDetailInfoEx1._uiGID);
        pstMainCtrl->m_stFriendMgr.BeInvitedRoleTrigger(stPlayerDetailInfoEx1,
            CFriendMgr::CMD_QQ_FRIEND_SUB_ADD_PAY_Q_COUNT, iQcent/10);
    }

    //OSS统计所有消费
    pstMainCtrl->m_stOssMgr.TriggerQQPay(stPlayerBaseInfo._uiGID, iQcent, atoi(stPara.GetValue("payamt_coins")),
        atoi(stPara.GetValue("pubacct_payamt_coins")), stPara.GetValue("billno"));

    //充值触发精彩活动(送魔晶等)
    pstMainCtrl->m_stActMgr.TriggerBuyGoods(stPlayerDetailInfo._stSplendidAct, stPlayerBaseInfo._uiGID,
        uiGoodsId, iCount, iQcent, stPlayerBaseInfo._stVipData._iPayGold);

    //保存数据
    if (bUpdateDetailEx1)
    {
        CVarObjectKey stKey;
        stKey.m_chDataType = DT_PLAYER_DETAIL_EX1_INFO;
        stKey.m_u64ID = uiGID;
        pstMainCtrl->UpdateData(stKey, stPlayerDetailInfoEx1, VOP_UPDATE);
    }

    stAns.msg.Set("OK");

    return AnsClients(RET_OK);
}

int CCmdSendGold::AnsClients(int iRet)
{
    stAns.ret = iRet;

    CTSizeString<1024> szSendBack;
    szSendBack.Set("{\"ret\":%d,\"msg\":\"%s\"}", stAns.ret, stAns.msg());

    pstMainCtrl->m_stEncodeBuf.Clear();
    memcpy(pstMainCtrl->m_stEncodeBuf.GetFreeBuf(), szSendBack(), szSendBack.GetDataLen());
    pstMainCtrl->m_stEncodeBuf.Append(szSendBack.GetDataLen());

    CT_TRACE(("CCmdSendGold::AnsClients %s", pstMainCtrl->m_stEncodeBuf.GetUsedBuf()));

    if (pstMainCtrl->AnswerToClient(stHead, pstMainCtrl->m_stEncodeBuf, true))
    {
        return Done(RET_SYS_ERROR);
    }

    int iIndex = pstMainCtrl->m_stPlayerOnlineDataHash.HashFind(uiGID);
    if (iIndex < 0)
    {
        CT_ERROR(("gid = %u", uiGID));
        return Done(RET_SYS_ERROR);
    }
    CPlayerOnlineData& stPlayerOnlineData = pstMainCtrl->m_stPlayerOnlineDataHash[iIndex];

    //应用发货通知
    CCmdApi* pstCmd = (CCmdApi*)CT_CMDFACTORY->CreateCmd(ID_MAINAPI_TAPI);
    if (!pstCmd)
    {
        CT_WARNING(("create cmd error"));
        return AnsClients(RET_SYS_ERROR);
    }

    pstCmd->pstMainCtrl = CMainCtrl::m_pstMain;
    pstCmd->stReq._ucReqType = CReqApi::API_TENCENT;
    pstCmd->stReq._szTApiName.Set("/v3/pay/confirm_delivery");

    CTSizeString<1024> szTmp;
    pstCmd->stReq._stTApiKeyValue = stPlayerOnlineData._stTencentApiKeyValue;

#if 0  //GM修改时间后的发货,要用服务器的原始时间
    struct timeval  stNowTime;
    gettimeofday(&stNowTime, NULL);
    szTmp.Set("%d", stNowTime.tv_sec);
#endif

    szTmp.Set("%d", pstMainCtrl->m_iNow);
    pstCmd->stReq._stTApiKeyValue.SetValue("ts", szTmp());

    pstCmd->stReq._stTApiKeyValue.SetValue("payitem", stPara.GetValue("payitem"));
    pstCmd->stReq._stTApiKeyValue.SetValue("token_id", stPara.GetValue("token"));
    pstCmd->stReq._stTApiKeyValue.SetValue("billno", stPara.GetValue("billno"));
    pstCmd->stReq._stTApiKeyValue.SetValue("version", stPara.GetValue("version"));
    pstCmd->stReq._stTApiKeyValue.SetValue("zoneid", stPara.GetValue("zoneid"));
    pstCmd->stReq._stTApiKeyValue.SetValue("providetype", stPara.GetValue("providetype"));

    szTmp.Set("%d", iRet);
    pstCmd->stReq._stTApiKeyValue.SetValue("provide_errno", szTmp());
    pstCmd->stReq._stTApiKeyValue.SetValue("provide_errmsg", stAns.msg());

    pstCmd->stReq._stTApiKeyValue.SetValue("amt", stPara.GetValue("amt"));
    pstCmd->stReq._stTApiKeyValue.SetValue("payamt_coins", stPara.GetValue("payamt_coins"));
    pstCmd->stReq._stTApiKeyValue.SetValue("pubacct_payamt_coins", stPara.GetValue("pubacct_payamt_coins"));

    pstCmd->Do(NULL);

    return Done(iRet);
}
